from matplotlib import pyplot as plt
from skimage import io, filters, color, feature, draw
from skimage import morphology
import numpy as np
from skimage.filters import threshold_otsu, threshold_local
from skimage.transform import (hough_line, probabilistic_hough_line, hough_circle, hough_circle_peaks)

# apply a Gaussian blur to an image
img = io.imread("images/astronaut.jpg")
gaussian_img = filters.gaussian(img, sigma=5, channel_axis=-1)
io.imshow(gaussian_img)
io.show()

# apply a Median filter to an image
median_img = np.zeros_like(img)
for i in range(img.shape[2]):
    median_img[:, :, i] = filters.median(img[:, :, i], morphology.disk(7))
io.imshow(median_img)
io.show()

# erosion
img2 = io.imread("images/linux.png")
grayscale_img2 = color.rgb2gray(img2)
binary_img = grayscale_img2 > 0.5
erosion_img = morphology.binary_erosion(binary_img, morphology.disk(2))
io.imshow(erosion_img)
io.show()

# dilation
dilation_img = morphology.binary_dilation(binary_img, morphology.disk(2))
io.imshow(dilation_img)
io.show()

# image threshold
grayscale_img = color.rgb2gray(img)
global_threshold = threshold_otsu(grayscale_img)
binary_global = grayscale_img > global_threshold
binary_adaptive = threshold_local(grayscale_img, 35, offset=10)
fig, axes = plt.subplots(nrows=3, figsize=(7, 8))
ax0, ax1, ax2 = axes
plt.gray()
ax0.imshow(grayscale_img)
ax0.set_title('Image')
ax1.imshow(binary_global)
ax1.set_title('Global thresholding')
ax2.imshow(binary_adaptive)
ax2.set_title('Adaptive thresholding')
for ax in axes:
    ax.axis('off')
plt.show()

# Sobel edge detector
sobel_edge_img = filters.sobel(grayscale_img)
io.imshow(sobel_edge_img)
io.show()

# Canny edge detector
canny_edge_img = feature.canny(grayscale_img, 3)
io.imshow(canny_edge_img)
io.show()

# Hough line
canny_edge2_img = feature.canny(grayscale_img2, 3)
lines = hough_line(grayscale_img2)
probabilistic_lines = probabilistic_hough_line(canny_edge2_img, threshold=10, line_length=5, line_gap=3)
lines_image = color.gray2rgb(grayscale_img2)
for line in probabilistic_lines:
    p0, p1 = line
    rr, cc = draw.line(p0[1], p0[0], p1[1], p1[0])
    lines_image[rr, cc] = (255, 0, 0)
io.imshow(lines_image)
io.show()
